home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Text⁄Files / MakeWrite / MakeWrite Folder / MWMapWind.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-22  |  21.2 KB  |  1,071 lines  |  [TEXT/KAHL]

  1. # include    "TransSkel.h"
  2.  
  3. # include    "MakeWrite.h"
  4.  
  5.  
  6. # define    tab            '\t'
  7.  
  8.  
  9. /*
  10.  * Local data for creating controls
  11.  */
  12.  
  13.  
  14. /*
  15.  * maxSize = number of point-size selection radio buttons
  16.  * maxStyle = number of style selection check boxes
  17.  * maxCP = number of edit menu cut/paste indicator controls
  18.  * maxCtrl = sum of above three
  19.  * maxFonts = maximum number of fonts allowed in scrollable list
  20.  */
  21.  
  22. # define    maxSize        7
  23. # define    maxStyle    9
  24. # define    maxCP        2
  25. # define    maxCtrl        (maxSize+maxStyle+maxCP)
  26. # define    maxFonts    102
  27.  
  28.  
  29. typedef enum    /* control types, by function */
  30. {
  31.     sizeType,    /* size radio button */
  32.     styleType,    /* style check box */
  33.     cpType        /* edit menu check box */
  34. };
  35.  
  36.  
  37. typedef struct CtrlInfo
  38. {
  39.     Str255    cTitle;        /* initial control title */
  40.     short        ch, cv;        /* location of upper left corner */
  41. } CtrlInfo;
  42.  
  43.  
  44. static CtrlInfo    ctrlInfo[maxCtrl] =
  45. {
  46.     { "\pSame",                181,    20 },
  47.     { "\p9",                172,    40 },
  48.     { "\p10",                172,    60 },
  49.     { "\p12",                172,    80 },
  50.     { "\p14",                217,    40 },
  51.     { "\p18",                217,    60 },
  52.     { "\p24",                217,    80 },
  53.     { "\pSame",                312,    20 },
  54.     { "\pPlain",            265,    40 },
  55.     { "\pBold",                265,    60 },
  56.     { "\pItalic",            265,    80 },
  57.     { "\pUnderline",        265,    100 },
  58.     { "\pOutline",            355,    40 },
  59.     { "\pShadow",            355,    60 },
  60.     { "\pSuperscript",        355,    80 },
  61.     { "\pSubscript",        355,    100 },
  62.     { "\pMarker",            9,        210 },
  63.     { "\pMap Lines",        9,        230 }
  64. };
  65.  
  66.  
  67. static ControlHandle    sizeCtrl[maxSize];
  68. static ControlHandle    styleCtrl[maxStyle];
  69. static ControlHandle    cpCtrl[maxCP];
  70.  
  71.  
  72.  
  73. /*
  74.  * Standard MacWrite point sizes, plus the "same size" selection.
  75.  * The order of these corresponds to the size radio buttons.
  76.  */
  77.  
  78. static short        sizeInfo[maxSize] = { sameSize, 9, 10, 12, 14, 18, 24 };
  79.  
  80.  
  81. /*
  82.  * Masks for manipulating style selections.  The order of these
  83.  * corresponds to the style check boxes.
  84.  */
  85.  
  86.  
  87. static short        styleMask[maxStyle] =
  88. {
  89.     sameStyle,
  90.     0,                /* plain; special-cased */
  91.     styleBold,
  92.     styleItalic,
  93.     styleUnder,
  94.     styleOutline,
  95.     styleShadow,
  96.     styleSuper,
  97.     styleSub
  98. };
  99.  
  100.  
  101. /*
  102.  * Standard font specifications
  103.  */
  104.  
  105.  
  106. typedef struct
  107. {
  108.     short            fontNum;
  109.     StringHandle    fontName;
  110. } FontSpec;
  111.  
  112.  
  113. static FontSpec    fontSpecs[maxFonts];
  114. static short    nFontSpecs;
  115.  
  116.  
  117. static short    fontOffsets[2] = { 0, 137 };
  118.  
  119.  
  120. static LineList    fontStruct =
  121. {
  122.     nil,                        /* port - filled in later        */
  123.     nil,                        /* control - filled in later     */
  124.     { 20, 5, 116, 141 },        /* text display rect, t, l, b, r */
  125.     0,                            /* max lines                     */
  126.     6,                            /* max visible lines             */
  127.     0,                            /* top visible line              */
  128.     16,                            /* line height                   */
  129.     0,                            /* number of lines               */
  130.     noLine,                        /* current line                  */
  131.     false,                        /* no hiliting                   */
  132.     1,                            /* number of fields/line         */
  133.     fontOffsets,                /* field offsets                 */
  134.     nil                            /* line array                    */
  135. };
  136.  
  137.  
  138. static LListPtr    fontList = &fontStruct;
  139.  
  140. static MapSpec    *curMSpec;
  141. static short        curMSpecNo;
  142.  
  143. static TEHandle    markTE;
  144.  
  145.  
  146. /* ---------------------------------------------------------------- */
  147. /*                    General Control Operations                        */
  148. /* ---------------------------------------------------------------- */
  149.  
  150.  
  151.  
  152. /*
  153.  * Set a control value, but only when it changes, to avoid
  154.  * unnecessary redrawing (ugly, since gobs of them are usually
  155.  * changed together).
  156.  *
  157.  * Use for check boxes and radio buttons only, not scroll bars!
  158.  */
  159.  
  160. static void
  161. SetControl (ControlHandle ctrl, Boolean value)
  162. {
  163.     if (GetCtlValue (ctrl) != value)
  164.         SetCtlValue (ctrl, value);
  165. }
  166.  
  167.  
  168. /* ---------------------------------------------------------------- */
  169. /*                        Font List Operations                        */
  170. /* ---------------------------------------------------------------- */
  171.  
  172.  
  173. /*
  174.  * Add a font to the spec list.  Return false if there's overrun.
  175.  */
  176.  
  177. Boolean
  178. SetFontSpec (short fNum, StringPtr fName)
  179. {
  180. StringHandle    h;
  181. Str255            s;
  182. short            i, result;
  183.  
  184.     for (i = 0; i < nFontSpecs; ++i)    /* see if already there */
  185.     {
  186.         h = fontSpecs[i].fontName;
  187.         HLock ((Handle) h);
  188.         result = CompareString (*h, fName);
  189.         HUnlock ((Handle) h);
  190.         if (result == 0)        /* font name's a duplicate */
  191.             return (true);        /* but that's ok */
  192.     }
  193.  
  194.     if (nFontSpecs >= fontList->maxLines)    /* will list be too full? */
  195.     {
  196.         NumToString ((long) maxFonts - 2, s);
  197.         Message3 ("\pSorry, I am such a brain-damaged program that I only allow ",
  198.                     s, "\p fonts!");
  199.         return (false);
  200.     }
  201.  
  202.     h = (StringHandle) NewHandle ((long) (fName[0] + 1));
  203.     HLock ((Handle) h);
  204.     CopyString (fName, *h);
  205.     HUnlock ((Handle) h);
  206.     fontSpecs[nFontSpecs].fontName = h;
  207.     fontSpecs[nFontSpecs++].fontNum = fNum;
  208.     return (true);
  209. }
  210.  
  211.  
  212. /*
  213.  * Set up to construct a new font list.  Note that the other
  214.  * selector controls must have been initialized by this point.
  215.  */
  216.  
  217. void
  218. ResetFontList (void)
  219. {
  220. short    i;
  221.  
  222.     for (i = 0; i < fontList->nLines; ++i)
  223.         DisposeHandle ((Handle) fontSpecs[i].fontName);
  224.     nFontSpecs = 0;
  225.     ResetList (fontList);
  226.     SetFontSpec (sameFont, "\pSame");
  227.     SetFontSpec (applFont, "\pApplication");
  228. }
  229.  
  230.  
  231. /*
  232.  * Sync information in fontSpec to fontList by constructing the LineList
  233.  * elements.
  234.  */
  235.  
  236. void
  237. SyncFontSpecs (void)
  238. {
  239. short        i, j;
  240. short        tmp;
  241. FontSpec    *f1, *f2;
  242. StringHandle    h1, h2;
  243. LineHandle        hField;
  244.  
  245.     /*
  246.      * Sort font names, except for "Same" and "Application", which
  247.      * stay at the front of the list.
  248.      */
  249.  
  250.     for (i = 2; i < nFontSpecs - 1; ++i)
  251.     {
  252.         for (j = i + 1; j < nFontSpecs; ++j)
  253.         {
  254.             f1 = &fontSpecs[i];
  255.             f2 = &fontSpecs[j];
  256.             h1 = f1->fontName;
  257.             h2 = f2->fontName;
  258.             HLock ((Handle) h1);
  259.             HLock ((Handle) h2);
  260.             if (CompareString (*h1, *h2) > 0)
  261.             {
  262.                 f1->fontName = h2;
  263.                 f2->fontName = h1;
  264.                 tmp = f1->fontNum;
  265.                 f1->fontNum = f2->fontNum;
  266.                 f2->fontNum = tmp;
  267.             }
  268.             HUnlock ((Handle) h1);
  269.             HUnlock ((Handle) h2);
  270.         }
  271.     }
  272.  
  273.     /*
  274.      * Add names to fontList
  275.      */
  276.  
  277.     ResetList (fontList);
  278.     for (i = 0; i < nFontSpecs; ++i)
  279.     {
  280.         h1 = fontSpecs[i].fontName;
  281.         HLock ((Handle) h1);
  282.         hField = NewLine (1);
  283.         SetFieldStr (hField, *h1);
  284.         HUnlock ((Handle) h1);
  285.         (void) InsertLine (fontList, hField, i);
  286.     }
  287.     SelectLine (fontList, 0);
  288.     ScrollToLine (fontList, 0);        /* force scroll to top */
  289. }
  290.  
  291.  
  292. /*
  293.  * Given a font number, find its index in the stdFontSpecs
  294.  * array.  Return -1 if it's not there.
  295.  */
  296.  
  297. short
  298. FontIndex (short fontNum)
  299. {
  300. short    i;
  301.  
  302.     for (i = 0; i < fontList->nLines; ++i)
  303.     {
  304.         if (fontNum == fontSpecs[i].fontNum)
  305.             return (i);
  306.     }
  307.     return (-1);
  308. }
  309.  
  310.  
  311. /*
  312.  * Return a font name corresponding to the given index
  313.  */
  314.  
  315. void
  316. FontName (short fontIndex, StringPtr str)
  317. {
  318. StringHandle    hStr;
  319.  
  320.     hStr = fontSpecs[fontIndex].fontName;
  321.     HLock ((Handle) hStr);
  322.     CopyString (*hStr, str);
  323.     HUnlock ((Handle) hStr);
  324. }
  325.  
  326.  
  327. /* ---------------------------------------------------------------- */
  328. /*                        Size Control Operations                        */
  329. /* ---------------------------------------------------------------- */
  330.  
  331.  
  332. /*
  333.  * Given a point size, find its index in the sizeInfo
  334.  * array.  (Return -1 if it's not there.)
  335.  */
  336.  
  337. short
  338. SizeIndex (short size)
  339. {
  340. short    i;
  341.  
  342.     for (i = 0; i < maxSize; ++i)
  343.     {
  344.         if (size == sizeInfo[i])
  345.             return (i);
  346.     }
  347.     return (-1);
  348. }
  349.  
  350.  
  351. static void
  352. SetSizeCtrls (void)
  353. {
  354. short    i;
  355.  
  356.     for (i = 0; i < maxSize; ++i)
  357.         SetControl (sizeCtrl[i], sizeInfo[i] == curMSpec->size);
  358. }
  359.  
  360.  
  361. /* ---------------------------------------------------------------- */
  362. /*                        Style Control Operations                    */
  363. /* ---------------------------------------------------------------- */
  364.  
  365.  
  366. /*
  367.  * Set the style controls based on the current value of theStyle.
  368.  *
  369.  * The sameStyle bit and the attributes bits cause the corresponding
  370.  * boxes to be checked if they are set.  If the style is zero, it's
  371.  * plain.
  372.  */
  373.  
  374. static void
  375. SetStyleCtrls (void)
  376. {
  377. short    i;
  378. Boolean    same;
  379. short    theStyle;
  380.  
  381.     theStyle = curMSpec->style;
  382.     same = ((theStyle & sameStyle) != 0);
  383.     SetControl (styleCtrl[0], same);
  384.  
  385.     if (same)
  386.     {
  387.         for (i = 1; i < maxStyle; ++i)
  388.             SetControl (styleCtrl[i], false);
  389.     }
  390.     else if (theStyle == 0)                    /* plain */
  391.     {
  392.         SetControl (styleCtrl[1], true);
  393.         for (i = 2; i < maxStyle; ++i)
  394.             SetControl (styleCtrl[i], false);
  395.     }
  396.     else                                    /* not plain */
  397.     {
  398.         SetControl (styleCtrl[1], false);
  399.         for (i = 2; i < maxStyle; ++i)
  400.             SetControl (styleCtrl[i], (theStyle & styleMask[i]) != 0);
  401.     }
  402. }
  403.  
  404.  
  405. /*
  406.  * Determine style value.  The argument is an index into the control
  407.  * array not a style value itself.  Style controls interact in
  408.  * wretched complexity.
  409.  *
  410.  * If same is toggled on, all the other style boxes are toggled off.
  411.  * If it's toggled off, plain is toggled on.
  412.  *
  413.  * If plain is toggled on, all the other style boxes are toggled off.
  414.  * If it's toggled off, same is toggled on.
  415.  *
  416.  * The other style boxes correspond to style attributes.  If any of
  417.  * them are toggled on, then same and plain are toggle off if
  418.  * they were on.  If all the attributes are toggled off, plain is
  419.  * toggled on.  Superscript and subscript are mutually exclusive,
  420.  * so that if one of them is toggled on, the other is toggled off.
  421.  */
  422.  
  423. static short
  424. NewStyleValue (short i)
  425. {
  426. short    curValue;
  427. short    theStyle;
  428.  
  429.     curValue = GetCtlValue (styleCtrl[i]);    /* current value - new value */
  430.                                             /* will be opposite */
  431.     theStyle = curMSpec->style;
  432.  
  433.     if (i == 0)            /* "same" box clicked */
  434.     {
  435.         if (curValue)    /*  currently same, turn off (implies plain) */
  436.             theStyle = 0;
  437.         else
  438.             theStyle = styleMask[0];    /* currently off, turn on */
  439.     }
  440.     else if (i == 1)    /* plain box clicked */
  441.     {
  442.         if (curValue)    /*  currently plain, turn off (implies same) */
  443.             theStyle = styleMask[0];
  444.         else
  445.             theStyle = 0;    /* currently off, turn on */
  446.     }
  447.     else
  448.     {
  449.         /*
  450.          * Flip box value.
  451.          * Can't have superscript and subscript at the same time.
  452.          */
  453.         if (curValue)    /* currently on, turn off */
  454.             theStyle &= ~styleMask[i];
  455.         else            /* currently off, turn on (turn same off) */
  456.         {
  457.             theStyle |= styleMask[i];
  458.             theStyle &= ~styleMask[0];
  459.         }
  460.  
  461.         if (i == 7)    /* superscript.  if turning on, turn off sub */
  462.         {
  463.             if (curValue == 0)
  464.                 theStyle &= ~styleMask[8];
  465.         }
  466.         if (i == 8)    /* subscript.  if turning on, turn off super */
  467.         {
  468.             if (curValue == 0)
  469.                 theStyle &= ~styleMask[7];
  470.         }
  471.     }
  472.     return (theStyle);
  473. }
  474.  
  475.  
  476. /* ---------------------------------------------------------------- */
  477. /*                Edit Menu Cut/Paste Control Operations                */
  478. /* ---------------------------------------------------------------- */
  479.  
  480.  
  481. static void
  482. SetCPCtrls (void)
  483. {
  484.     SetControl (cpCtrl[0], cpMarker);
  485.     SetControl (cpCtrl[1], !cpMarker);
  486. }
  487.  
  488.  
  489. void
  490. SetCPMarker (Boolean useMarker)
  491. {
  492.     cpMarker = useMarker;
  493.     SetCPCtrls ();
  494. }
  495.  
  496.  
  497. void
  498. BlankCPCtrls (void)
  499. {
  500.     SetControl (cpCtrl[0], false);
  501.     SetControl (cpCtrl[1], false);
  502. }
  503.  
  504.  
  505. /* ---------------------------------------------------------------- */
  506. /*                            Marker Operations                        */
  507. /* ---------------------------------------------------------------- */
  508.  
  509.  
  510. /*
  511.  * Sync the marker edit text to a mapSpec
  512.  */
  513.  
  514. void
  515. MSpecToMark (MapSpec *m)
  516. {
  517. StringHandle    s;
  518. Rect            r;
  519.  
  520.     s = m->mark;
  521.     HLock ((Handle) s);
  522.     TESetSelect (0L, 32767L, markTE);
  523.     TEDelete (markTE);
  524.     TEInsert (*s + 1, (long) (*s)[0], markTE);    /* replace text */
  525.     HUnlock ((Handle) s);
  526.     TESetSelect ((long) m->selStart, (long) m->selEnd, markTE);
  527. }
  528.  
  529.  
  530. /*
  531.  * Sync current mapSpec to the marker edit text
  532.  */
  533.  
  534. static void
  535. MarkToMSpec (void)
  536. {
  537. StringHandle    hStr;
  538. Handle            h;
  539. short            len;
  540.  
  541.     curMSpec->selStart = (**markTE).selStart;
  542.     curMSpec->selEnd = (**markTE).selEnd;
  543.     h = (Handle) TEGetText (markTE);
  544.     len = (**markTE).teLength;
  545.     if (len > maxMarkLen)
  546.         len = maxMarkLen;        /* truncate length if necessary */
  547.     hStr = curMSpec->mark;
  548.     HLock (h);
  549.     HLock ((Handle) hStr);
  550.     BlockMove (*h, *hStr + 1, (long) len);
  551.     (*hStr)[0] = len;
  552.     HUnlock (h);
  553.     PasteField (mapList, mapList->curLine, markField, *hStr);
  554.     HUnlock ((Handle) hStr);
  555. }
  556.  
  557.  
  558. typedef enum        /* relevant Edit menu item numbers */
  559. {
  560.     cut = 3,
  561.     copy,
  562.     paste,
  563.     clear
  564. };
  565.  
  566.  
  567. void
  568. MarkerUndoSetup (void)
  569. {
  570.     CopyMSpec (curMSpec, &undoMSpec);
  571.     undoOp = undoMarkerOp;
  572.     undoPos = mapList->curLine;
  573.     undoCPMarker = cpMarker;
  574. }
  575.  
  576.  
  577. Boolean
  578. EditMarker (short item)
  579. {
  580.     if (!cpMarker)
  581.         return (false);
  582.  
  583.     switch (item)
  584.     {
  585.     
  586.     case cut:
  587.         MarkerUndoSetup ();
  588.         TECut (markTE);
  589.         (void) ZeroScrap ();
  590.         (void) TEToScrap ();
  591.         break;
  592.     
  593.     case copy:
  594.         TECopy (markTE);
  595.         (void) ZeroScrap ();
  596.         (void) TEToScrap ();
  597.         break;
  598.     
  599.     case paste:
  600.         if (curMSpec == nil)    /* ignore if no line selected */
  601.             return (false);
  602.         MarkerUndoSetup ();
  603.         (void) TEFromScrap ();
  604.         TEPaste (markTE);
  605.         break;
  606.     
  607.     case clear:
  608.         MarkerUndoSetup ();
  609.         (void) TEDelete (markTE);
  610.         break;
  611.     
  612.     default:
  613.         return (false);    /* all others handled by general */
  614.                         /* edit menu handler */
  615.  
  616.     }
  617.  
  618.     MarkToMSpec (/*curMSpec*/);    /* sync map with change in mark */
  619.     if (item != copy)
  620.         mapModified = true;
  621.     FixMenus ();
  622.     return (true);
  623. }
  624.  
  625.  
  626. /* ---------------------------------------------------------------- */
  627.  
  628.  
  629. /*
  630.  * Set a field in the currently selected line.  Don't call this if
  631.  * no line is selected, or if the field already has the same value.
  632.  */
  633.  
  634. void
  635. SetMapFieldValue (short fieldType, short value)
  636. {
  637. Str255        s;
  638.  
  639.     switch (fieldType)
  640.     {
  641.  
  642.     case fontField:
  643.         undoVal = curMSpec->font;
  644.         FontToStr (value, s);
  645.         curMSpec->font = value;
  646.         SelectLine (fontList, FontIndex (value));
  647.         break;
  648.  
  649.     case sizeField:
  650.         undoVal = curMSpec->size;
  651.         SizeToStr (value, s);
  652.         curMSpec->size = value;
  653.         SetSizeCtrls ();
  654.         break;
  655.  
  656.     case styleField:
  657.         undoVal = curMSpec->style;
  658.         StyleToStr (value, s);
  659.         curMSpec->style = value;
  660.         SetStyleCtrls ();
  661.         break;
  662.     }
  663.  
  664.     PasteField (mapList, mapList->curLine, fieldType, s);
  665.     mapModified = true;
  666.     undoOp = undoFieldChg;
  667.     undoFieldType = fieldType;
  668. }
  669.  
  670.  
  671. /*
  672.  * Set the selection controls and font list to reflect currently
  673.  * selected conversion specification.  Also sets current MapSpec
  674.  * pointer.
  675.  */
  676.  
  677. void
  678. SetSelectors (short lineNo)
  679. {
  680. short    i;
  681.  
  682.     if (lineNo == noLine)                /* no map line selected */
  683.     {
  684.  
  685.         curMSpec = nil;
  686.         curMSpecNo = noLine;
  687.  
  688.         ListActivate (fontList, false);
  689.     
  690.         for (i = 0; i < maxSize; ++i)
  691.             SetControl (sizeCtrl[i], false);
  692.     
  693.         for (i = 0; i < maxStyle; ++i)
  694.             SetControl (styleCtrl[i], false);
  695.  
  696.         TESetSelect (0L, 32767L, markTE);
  697.         TEDelete (markTE);
  698.         TEDeactivate (markTE);
  699.  
  700.         return;
  701.     }
  702.  
  703.     curMSpec = &mapSpec[curMSpecNo = lineNo];
  704.  
  705.     SelectLine (fontList, FontIndex (curMSpec->font));
  706.     ListActivate (fontList, true);
  707.     ScrollToLine (fontList, fontList->curLine);
  708.     SetSizeCtrls ();
  709.     SetStyleCtrls ();
  710.     MSpecToMark (curMSpec);
  711.     TEActivate (markTE);
  712.     /*SetCPCtrls ();*/
  713. }
  714.  
  715.  
  716. /*
  717.  * Map window mouse handler.
  718.  *
  719.  * First test the scroll bars, and return if one was hit; they
  720.  * require no further action.
  721.  *
  722.  * Then check for hit in map list.  If a new line was selected, set
  723.  * the selectors to the values, and disable undo.
  724.  *
  725.  * Then, if a line is currently selected, check the selection controls.
  726.  * If one is hit, change the values in the current line and reset the
  727.  * controls properly - but only if the current values *change*.
  728.  */
  729.  
  730. static pascal void
  731. Mouse (Point pt, long t, short mods)
  732. {
  733. ControlHandle    ctrl;
  734. short            index;
  735. short            type;
  736. long            refCon;
  737. short            newVal;
  738. Boolean            newIO;
  739. short            curLine;
  740. Rect            r;
  741.  
  742.     if (ListTestScroll (mapList, pt) || ListTestScroll (fontList, pt))
  743.         return;
  744.  
  745.     curLine = mapList->curLine;                /* current line */
  746.     if (ListTestText (mapList, pt))
  747.     {
  748.         if (curLine != mapList->curLine)    /* different now? */
  749.         {
  750.             undoOp = noUndo;
  751.             if ((curLine = mapList->curLine) != noLine)
  752.             {
  753.                 mapSpec[curLine].selStart = 0;
  754.                 mapSpec[curLine].selEnd = 32767;
  755.             }
  756.             /*SetCPMarker (true);*/
  757.             SetSelectors (curLine);
  758.             FixMenus ();
  759.         }
  760.         return;
  761.     }
  762.  
  763.     if (curMSpec == nil)
  764.         return;                /* no current line - controls irrelevant */
  765.  
  766.     if (ListTestText (fontList, pt))
  767.     {
  768.         if (fontList->curLine == noLine)
  769.             SelectLine (fontList, fontList->nLines - 1);
  770.         newVal = fontSpecs[fontList->curLine].fontNum;    
  771.         if (curMSpec->font != newVal)
  772.         {
  773.             SetMapFieldValue (fontField, newVal);
  774.             FixMenus ();
  775.         }
  776.         return;
  777.     }
  778.  
  779.     /*
  780.      * Check the edittext box
  781.      */
  782.  
  783.     r = (**markTE).viewRect;
  784.     InsetRect (&r, -3, -3);
  785.     if (PtInRect (pt, &r))
  786.     {
  787.         undoOp = noUndo;
  788.         SetCPMarker (true);
  789.         TEClick (pt, (mods & shiftKey) != 0, markTE);
  790.         curMSpec->selStart = (**markTE).selStart;
  791.         curMSpec->selEnd = (**markTE).selEnd;
  792.         FixMenus ();
  793.         return;
  794.     }
  795.  
  796.     /*
  797.      * Don't need to check control type returned from FindControl - at
  798.      * this point, it can't be anything but inCheckBox.  The control type
  799.      * and index is coded in the reference constant (see MakeControl).
  800.      */
  801.  
  802.     if (FindControl (pt, mapWind, &ctrl))
  803.     {
  804.         if (TrackControl (ctrl, pt, nil) == inCheckBox)
  805.         {
  806.             refCon = GetCRefCon (ctrl);
  807.             index = refCon & 0x00ff;
  808.             type = (refCon & 0xff00) >> 8;
  809.  
  810.             switch (type)
  811.             {
  812.  
  813.             case sizeType:
  814.                 newVal = sizeInfo[index];
  815.                 if (newVal != curMSpec->size)
  816.                     SetMapFieldValue (sizeField, newVal);
  817.                 break;
  818.  
  819.             case styleType:
  820.                 newVal = NewStyleValue (index);
  821.                 if (newVal != curMSpec->style)
  822.                     SetMapFieldValue (styleField, newVal);
  823.                 break;
  824.  
  825.             case cpType:
  826.                 SetCPMarker (index == 0);
  827.                 undoOp = noUndo;
  828.                 break;
  829.  
  830.             }
  831.  
  832.             FixMenus ();
  833.         }
  834.         return;
  835.     }
  836. }
  837.  
  838.  
  839. /*
  840.  * Process key click in window for mark string.  On the first key
  841.  * after any other operation, save the current mark string state
  842.  * for undo.  And on every key click, save the selection range.  This
  843.  * is so the range can be saved properly if the window is inactivated
  844.  * and later activated, or if another line is selected and then this
  845.  * line is reselected.
  846.  */
  847.  
  848. static pascal void
  849. Key (short c, short code, short mods)
  850. {
  851. Handle            h;
  852. StringHandle    s;
  853. short                len;
  854.  
  855.     if (curMSpec == nil)
  856.         return;
  857.  
  858.     switch (c)
  859.     {
  860.     
  861.     case tab:
  862.     case enter:
  863.     case cr:
  864.         undoOp = noUndo;
  865.         if (mods & shiftKey)
  866.         {
  867.             if (--curMSpecNo < 0)
  868.                 curMSpecNo = mapList->nLines - 1;
  869.         }
  870.         else
  871.         {
  872.             if (++curMSpecNo >= mapList->nLines)
  873.                 curMSpecNo = 0;
  874.         }
  875.         SelectMapping (curMSpecNo);
  876.         break;
  877.  
  878.     default:
  879.         if (undoOp != undoTyping)    /* first char typed */
  880.         {
  881.             MarkerUndoSetup ();
  882.             undoOp = undoTyping;
  883.         }
  884.  
  885.         TEKey (c, markTE);
  886.         MarkToMSpec (/*curMSpec*/);
  887.         SetCPMarker (true);
  888.         mapModified = true;
  889.         FixMenus ();
  890.  
  891.     }
  892. }
  893.  
  894.  
  895. static pascal void
  896. Update (Boolean resized)
  897. {
  898. short    i;
  899. Rect    r;
  900.  
  901.     MoveTo (65, 14);
  902.     DrawString ("\pFont");
  903.     MoveTo (180, 14);
  904.     DrawString ("\pPoint Size");
  905.     MoveTo (322, 14);
  906.     DrawString ("\pStyle");
  907.     MoveTo (30, 145);
  908.     DrawString ("\pMarker");
  909.     MoveTo (4, 190);
  910.     DrawString ("\pCut & Paste Ops");
  911.     MoveTo (4, 206);
  912.     DrawString ("\pAffect:");
  913.     MoveTo (212, 143);
  914.     DrawString ("\pFormat Specifications");
  915.     DrawControls (mapWind);
  916.     r = (**markTE).viewRect;
  917.     EraseRect (&r);
  918.     TEUpdate (&r, markTE);
  919.     InsetRect (&r, -3, -3);
  920.     FrameRect (&r);
  921.     DrawListFrame (fontList);
  922.     DrawListFrame (mapList);
  923.     DrawListText (fontList);
  924.     DrawListText (mapList);
  925. }
  926.  
  927.  
  928. /*
  929.  * When the window is activated, do appropriate map list and font list
  930.  * line and scroll bar hiliting, and set size and style controls to
  931.  * current values.
  932.  *
  933.  * When the window is deactivated, all hiliting is turned off, the
  934.  * scroll bars are unhilited and the size and style controls go blank.
  935.  *
  936.  * Note that SetSelectrs takes care of setting font list line and scroll
  937.  * bar hiliting; it doesn't have to be done here.  It also activates
  938.  * or deactivates the text field properly.
  939.  */
  940.  
  941. static pascal void
  942. Activate (Boolean active)
  943. {
  944.     if (active)
  945.     {
  946.         SkelDoUpdates ();
  947.         ListActivate (mapList, true);
  948.         SetSelectors (mapList->curLine);
  949.     }
  950.     else
  951.     {
  952.         SetSelectors (noLine);
  953.         ListActivate (mapList, false);
  954.     }
  955.     FixMenus ();
  956. }
  957.  
  958.  
  959. static pascal void
  960. Clobber (void)
  961. {
  962.     HideWindow (mapWind);
  963.     TEDispose (markTE);
  964.     /*DisposeList (mapList);
  965.     DisposeList (fontList);*/
  966.     DisposeWindow (mapWind);
  967. }
  968.  
  969.  
  970. static pascal void
  971. Idle (void)
  972. {
  973.     TEIdle (markTE);
  974. }
  975.  
  976.  
  977. /*
  978.  * Create controls.  These are created in the same order as the specs
  979.  * in the ctrlInfo array.
  980.  */
  981.  
  982. static ControlHandle
  983. MakeControl (short proc, short type, short index)
  984. {
  985. static short    i = 0;    /* used to step through ctrlInfo array */
  986. CtrlInfo    *cInfo;
  987. Rect        r;
  988. StringPtr    title;
  989. short        h, v;
  990. ControlHandle    ctrl;
  991.  
  992.     cInfo = &ctrlInfo[i++];
  993.     title = cInfo->cTitle;
  994.     h = cInfo->ch;
  995.     v = cInfo->cv;
  996.     SetRect (&r, h, v, h + StringWidth (title) + 20, v + 20);
  997.     ctrl = NewControl (mapWind,
  998.                         &r,
  999.                         title,
  1000.                         true,
  1001.                         0, 0, 1,
  1002.                         proc,
  1003.                         (long) (type << 8 | index));
  1004.     return (ctrl);
  1005. }
  1006.  
  1007.  
  1008. void
  1009. MapSetup (void)
  1010. {
  1011. short    i;
  1012. Rect    r;
  1013.  
  1014.     SetRect (&r, 0, 0, 456, 251);
  1015.     if (SkelQuery (skelQHasColorQD))
  1016.     {
  1017.         mapWind = NewCWindow (nil, &r, "\p", false, noGrowDocProc,
  1018.                                 (WindowPtr) -1L, false, 0L);
  1019.     }
  1020.     else
  1021.     {
  1022.         mapWind = NewWindow (nil, &r, "\p", false, noGrowDocProc,
  1023.                                 (WindowPtr) -1L, false, 0L);
  1024.     }
  1025.     SkelWindow (mapWind,
  1026.                 Mouse,
  1027.                 Key,
  1028.                 Update,
  1029.                 Activate,
  1030.                 nil,
  1031.                 Clobber,
  1032.                 Idle,
  1033.                 true);
  1034.  
  1035.     TextFont (0);            /* do this so StringWidth calculations */
  1036.     TextSize (0);            /* for controls will be accurate */
  1037.  
  1038.     for (i = 0; i < maxSize; ++i)
  1039.         sizeCtrl[i] = MakeControl (radioButProc, sizeType, i);
  1040.  
  1041.     for (i = 0; i < maxStyle; ++i)
  1042.         styleCtrl[i] = MakeControl (checkBoxProc, styleType, i);
  1043.  
  1044.     for (i = 0; i < maxCP; ++i)
  1045.         cpCtrl[i] = MakeControl (radioButProc, cpType, i);
  1046.  
  1047.     SetRect (&r, 7, 152, 107, 168);
  1048.     markTE = TENew (&r, &r);
  1049.     (void) ZeroScrap ();
  1050.  
  1051.     InitList (fontList, maxFonts);        /* initialize empty list */
  1052.     InitList (mapList, maxMappings);
  1053.     for (i = 0; i < maxMappings; ++i)
  1054.         InitMSpec (&mapSpec[i]);
  1055.  
  1056.     /*
  1057.      * Add default set of fonts:  ImageWriter fonts and LaserWriter fonts.
  1058.      * Reset the list and add the two sets without asking whether to add to
  1059.      * or replace the current list, since there's not really any current
  1060.      * list.
  1061.      */
  1062.  
  1063.     ResetFontList ();
  1064.     StrFonts (false);
  1065.  
  1066.     ClearMapName ();
  1067.     SkelPositionWindow (mapWind, skelPositionOnMainDevice,
  1068.                                     FixRatio (1, 2), FixRatio (1, 5));
  1069.     ShowWindow (mapWind);
  1070. }
  1071.